import {replaceByObj} from './xUtil.js'
import xID from "./xID.js";
import {findJsonByCode} from "./treeUtil.js";
/*
 data:[{code,name,tag}];

 */


const splitChar = ' , ';
const tmplBase = `<div class="{{class}}"  >
                    <div type="head" class="xhead">                        
                        <input   readonly="readonly" class="xinput-icon"/>   
                        <i class="iconfont icon-dropdown after-icon-set"></i>                                         
                    </div>
                    <div type ="main" class="xmain"> 
                        <div type="body">
                            <table><tbody></tbody></table>
                        </div>                    
                        <div  type="footer" >                                                 
                            <label  type ="all">
                               <input class="form-check-input" type="checkbox"  key="all"/> 
                               全选
                            </label>                          
                            <button type ="cancel" class="btn btn-sm btn-secondary">  取消 </button>                         
                            <button type ="ok" class="btn btn-sm btn-primary"> 确认 </button>						                          
                        </div>
                    </div>
                 </div>  `;

const tmplTag = '<td {{colspan}} ><label type="tag">{{tag}}</label></td>'
const tmplTr = '<tr>{{trHtml}}</tr>'
const tmplTd = '<td>{{tdHtml}}</td>'
const mselectItem = `<label  type ="item">
                        <input type="checkbox" {{checked}} data-code="{{code}}" class="form-check-input" key ="item"/>
                        {{name}}
                 </label> `
const tmplTitle = `title="{{title}}"`;
export default class mSelect {
	/* 定义变量 开始*/
	// jquery 对象
    vCfg;
	$tbody ;
	$root;
	$head;
	$input;
	$main;
	vSelect = [];
    vBindEvent;
    vClickId = 'click.'+xID.getID();

	/* 定义变量 结束*/

	constructor(cfg) {
	    this.vCfg=cfg;
		this.$root = $('#' + cfg.el);
		this.$root.html(tmplBase.replace('{{class}}', cfg.style||'mselect'));
        this.renderInit();
        if(this.vCfg.active)
            this.initValue(this.vCfg.active)
	};

    initValue(value){
        if(value && value.length>0){
            if((this.vCfg.valueType||'code') =='code'){
                this.vSelect=[];
                value.forEach(item => this.vSelect.push(findJsonByCode(this.vCfg.data,item)))
            }else
                this.vSelect = value;
        }
        else
            this.vSelect = [];
        this.renderHead();
        this.verify();
    }
	/* 渲染区块 开始 */
	renderInit() {

        this.$main = this.$root.find('[type="main"]');
		this.$tbody = this.$root.find('tbody');
        this.$head = this.$root.find('[type="head"]');
        this.$input = this.$head.find('input');
        this.$main.hide();
        this.renderHead();
		//事件处理
		this.$root.on('click', '[key="all"]', this.evSelectAll.bind(this));
		this.$root.on('click', '[type="ok"]', this.evOk.bind(this));
		this.$root.on('click', '[type="cancel"]', this.evCancel.bind(this));
        this.$input.on('focus',this.evFocus.bind(this));
        this.$root.on('keydown',this.evKeydown.bind(this));
        this.$root.on('click', '[key="item"]', this.evItemChecked.bind(this));
        this.$head.on('click', this.evDropDown.bind(this));

        let title ='';
        if(this.vCfg.title)
            title = tmplTitle.replace("{{title}}",this.vCfg.title);
        if(this.vCfg.placeholder)
            this.$input.attr("placeholder",this.vCfg.placeholder);

        this.$head.attr("title",title);
	};

    renderStatus(action,status){
        if(action=='add'){
            this.$head.addClass(status);
        }else{
            this.$head.removeClass(status);
        }
    }

    renderHead(){
        let names =[];
        this.vSelect.forEach(value => names.push(value.name||value.code) );
        this.$input.attr('value',names.join(splitChar));
    }

    renderBody() {
        if( this.vCfg.data && this.vCfg.data.length>0){
            let cols = this.vCfg.cols || 1;
            let [tds,trs,tag] = ['','',''];
            let j = 0;
            for(let i=0;i<this.vCfg.data.length;i++){
                let item = this.vCfg.data[i];

                if(this.vCfg.tag && tag != item.tag){
                    if(tds.length>0){
                        trs += tmplTr.replace('{{trHtml}}', tds);
                        tds = '';
                    }

                    tag =  item.tag
                    trs += tmplTr.replace('{{trHtml}}', this.renderTagTd(tag,cols));
                    j=0;
                }

                tds += tmplTd.replace('{{tdHtml}}',this.renderItem(item));
                j +=1;
                if(j>=cols || i==this.vCfg.data.length-1){
                    trs += tmplTr.replace('{{trHtml}}', tds);
                    tds ='';
                    j=0;
                }

            }

            this.$tbody.html(trs);
            this.renderAllStatus();
        }
    }

    renderItem(item){
        let obj ={code:item.code,name:item.name||item.code};
        //checked判断
        let codes=[];
        this.vSelect.forEach(value => codes.push(value.code));
        obj.checked = codes.includes(item.code)?'checked':'';
        return replaceByObj(mselectItem,obj);
    }

    renderTagTd(tag,rowSize){
        return replaceByObj(tmplTag,{tag,colspan:rowSize==1?'':'colspan="'+rowSize+'"'});
    }

    renderAllStatus(){
        if(this.vCfg.data){
            if(this.vCfg.data.length>0 && this.vSelect.length == this.vCfg.data.length)
                this.$root.find('input[key="all"]')[0].checked =  true
            else
                this.$root.find('input[key="all"]')[0].checked =  false;
        }

    }

	evSelectAll(e) {
		let checked = e.target.checked;
		this.$root.find('input[key="item"]').each((index, item) => {
			item.checked = checked;
		});
	};

    evItemChecked(e) {
        let length = this.$root.find('input[key="item"]:checked').length;
        if(length && length == this.vCfg.data.length)
            this.$root.find('input[key="all"]')[0].checked =  true
        else
            this.$root.find('input[key="all"]')[0].checked =  false;
    };

    evKeydown(e){
        let keynum = window.event ? e.keyCode : e.which;
        switch(keynum){
            //enter
            case 13:
                break;
            //tab 失去焦点
            case 9:
                this.evOff.bind(this)(e);
                break;
            // esc
            case 27:
                this.$main.hide();
                break;
        }
    }

	evOk(e) {
		this.vSelect = [];
		this.$root.find('input[key="item"]').each((index, item) => {
			if(item.checked) {
				this.vSelect.push(findJsonByCode(this.vCfg.data,item.getAttribute("data-code")));
			}
		});
		this.renderHead();
        this.$input[0].focus();
        this.$main.hide();
        if(this.vBindEvent){
            if((this.vCfg.valueType||'code') =='code'){
                let codes = [];
                this.vSelect.forEach(item => codes.push(item.code));
                this.vBindEvent(codes);
            }
            else
                this.vBindEvent(this.vSelect);
        }
	};

	evCancel(e) {
        this.$main.hide();
	};

    evDropDown(e) {
        if(this.$main.is(':visible'))
            return;
        this.renderStatus("add","active");
        this.renderBody();
        if(this.vCfg.placement=='top'){
            let pos = this.$head.outerHeight()+1;
            this.$main.css("bottom",pos+"px");
        }
        this.$main.show();
        $(document).on(this.vClickId,this.evOff.bind(this));
    };

    evFocus(e){
        this.evDropDown(null);
    }


    evOff(e){
        /*如果是 tab 事件 如果 document.activeElement  this*/
        if((e.type=='keydown' && (this.$main.is(':hidden') || document.activeElement.getAttribute('type')=='ok')) ||
            (e.type=='click' && this.$root.find(e.target).length<1)){
            this.$main.hide();
            this.renderStatus('remove','active');
            this.verify();
            $(document).unbind(this.vClickId);
        }
    }

	/*click  事件处理 区块 结束*/
    setBindEvent(event){
        this.vBindEvent = event;
    };

    setData(data){
        this.vCfg.data =data;
    }

    setValue(value){
        this.initValue(value);
    };

    verify() {
        let result = true;
        if(this.vCfg.mandatory ){
            if(this.vSelect.length<1){
                this.renderStatus("remove",'valid');
                this.renderStatus("add","invalid");
                result =false
            }else {
                this.renderStatus("remove",'invalid');
                this.renderStatus("add","valid");
            }
        }
        return result;
    }

    getSelect(){
        return this.vSelect;
    }

}